home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / UI / WinPopM.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  21.9 KB  |  837 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        WinPopM.cpp
  3.  
  4.     Contains:    The Document Path pop-up menu
  5.  
  6.     Owned by:    Jens Alfke
  7.  
  8.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <10>     10/4/95    jpa        Fixed ref-count bugs in WalkFrameHierarchy.
  13.                                     [1285639]
  14.          <9>     8/29/95    jpa        Fixes for Univ Hdrs 2.1 & CW7 [1279173]
  15.          <8>     8/25/95    JP        1254840: ODGetIconFamily part to frame
  16.                                     fallout
  17.          <7>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  18.                                     file.
  19.          <6>     8/15/95    CC        1275241: Added #include of Aliases.h
  20.          <5>      8/8/95    jpa        Fixed DebugStr [1265584]
  21.          <4>     7/26/95    DM        #1270320: Memory leak fixes: dispose desc
  22.                                     in RevealFinderIcon
  23.          <3>     6/29/95    jpa        Use container ID to get document file spec.
  24.                                     [1261806] Add "Desktop" to pop-up when doc
  25.                                     path ends at desktop. [1262681]
  26.          <2>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  27.                                     refcount is wrong in
  28.                                     ODRefCntObjectsomUninit.
  29.          <1>     6/19/95    jpa        first checked in
  30.  
  31.     In Progress:
  32.         
  33. */
  34.  
  35.  
  36. #ifndef _WINPOPM_
  37. #include "WinPopM.h"
  38. #endif
  39.  
  40. #ifndef _WINDOW_
  41. #include "Window.xh"
  42. #endif
  43.  
  44. #ifndef _WINSTAT_
  45. #include "WinStat.xh"
  46. #endif
  47.  
  48. #ifndef _DISPTCH_
  49. #include "Disptch.xh"
  50. #endif
  51.  
  52. #ifndef _UIDEFS_
  53. #include "UIDefs.h"
  54. #endif
  55.  
  56. #ifndef _DOCUMENT_
  57. #include <Document.xh>
  58. #endif
  59.  
  60. #ifndef _FRAME_
  61. #include <Frame.xh>
  62. #endif
  63.  
  64. #ifndef _ODCTR_
  65. #include <ODCtr.xh>
  66. #endif
  67.  
  68. #ifndef _ODSTOR_
  69. #include <ODStor.xh>
  70. #endif
  71.  
  72. #ifndef _PARTWRAP_
  73. #include <PartWrap.xh>
  74. #endif
  75.  
  76. #ifndef _LINKMGR_
  77. #include <LinkMgr.xh>
  78. #endif
  79.  
  80. #ifndef _DRAGDRP_
  81. #include <DragDrp.xh>
  82. #endif
  83.  
  84. #ifndef _SHAPE_
  85. #include <Shape.xh>
  86. #endif
  87.  
  88. #ifndef _NMSPCMG_
  89. #include <NmSpcMg.xh>
  90. #endif
  91.  
  92. #ifndef _VALUENS_
  93. #include <ValueNS.xh>
  94. #endif
  95.  
  96. #ifndef _STDDEFS_
  97. #include <StdDefs.xh>
  98. #endif
  99.  
  100. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  101. #include <StdTypes.xh>
  102. #endif
  103.  
  104. #ifndef _BNDNSUTL_
  105. #include <BndNSUtl.h>
  106. #endif
  107.  
  108. #ifndef _INFOUTIL_
  109. #include <InfoUtil.h>
  110. #endif
  111.  
  112. #ifndef _PASCLSTR_
  113. #include <PasclStr.h>
  114. #endif
  115.  
  116. #ifndef _ISOSTR_
  117. #include <ISOStr.h>
  118. #endif
  119.  
  120. #ifndef _PLFMFILE_
  121. #include <PlfmFile.h>
  122. #endif
  123.  
  124. #ifndef _USERSRCM_
  125. #include <UseRsrcM.h>
  126. #endif
  127.  
  128. #ifndef _TEMPOBJ_
  129. #include <TempObj.h>
  130. #endif
  131.  
  132. #ifndef _UTILERRS_
  133. #include "UtilErrs.h"
  134. #endif
  135.  
  136. #ifndef __ERRORS__
  137. #include <Errors.h>
  138. #endif
  139.  
  140. #ifndef __TOOLUTILS__
  141. #include <ToolUtils.h>                    // For BitTst()
  142. #endif
  143.  
  144. #ifndef __ICONS__
  145. #include <Icons.h>
  146. #endif
  147.  
  148. #ifndef __FOLDERS__
  149. #include <Folders.h>
  150. #endif
  151.  
  152. #ifndef __ALIASES__
  153. #include <Aliases.h>
  154. #endif
  155.  
  156. #ifndef __DEVICES__
  157. #include <Devices.h>
  158. #endif
  159.  
  160. #include <stdlib.h>
  161.  
  162. typedef Handle IconSuite;
  163.  
  164.  
  165. const ODSShort kUseSpecificScript = 0x1c;    // Script mgr code for menu items
  166.  
  167. const short kFloppyDriverRefNum = 0xFFFB;    // Floppy (.SONY) driver refnum
  168.  
  169. const Point kMenuOffset = {1,-36};        // Menu offset from window title
  170.  
  171. const short kDefaultDocIconID =   128;    // A default OpenDoc part icon (small sizes only)
  172. const short kPartPopUpMenuID  =  9000;    // Menu ID of title-bar pop-up
  173. const short kGenericPartSICNID=   263;    // SICN ID of generic part icon
  174.  
  175. const  short kKindIconBase = 7;            // Icon# (rsrc ID -256) of 1st reserved icon for parts
  176. const  short kMaxNKindIcons = 5;
  177.  
  178.  
  179. static short gNKindIcons;
  180. static ODType gIconKind[kMaxNKindIcons];
  181.  
  182.  
  183. static short    TitlePopUpSelect( WindowPtr w, const FSSpec &doc, MenuHandle m, Point where );
  184. static ODFrame*     WalkFrameHierarchy( Environment *, ODFrame *, MenuHandle, short stopAtItem =32767 );
  185. static OSErr    RevealFinderIcon( const FSSpec &itemToReveal, const FSSpec &parentFolder );
  186. static    OSErr    GetParentID(short vRefNum,
  187.                             long dirID,
  188.                             StringPtr name,
  189.                             long *parID);
  190. static    OSErr    GetDirName(short vRefNum,
  191.                            long dirID,
  192.                            StringPtr name);
  193. static    OSErr    FSpGetFileLocation(short refNum,
  194.                                    FSSpec *spec);
  195. static ODBoolean VolumeIsFloppy( short vRefNum );
  196.  
  197.  
  198. #pragma segment PathPopUp
  199.  
  200.  
  201. //==============================================================================
  202. #pragma mark    UTILITIES
  203. //==============================================================================
  204.  
  205.  
  206. static ODDocument*
  207. GetDocument( Environment *ev, ODWindow *w )
  208. {
  209.     return w->GetDraft(ev)->GetDocument(ev);
  210. }
  211.  
  212. static void
  213. GetDocumentFileSpec( Environment *ev, ODWindow *w, FSSpec &fss )
  214. {
  215.     TempODContainerIDStruct id(GetDocument(ev,w)->GetContainer(ev)->GetID(ev));
  216.     ASSERT(id->_length>=8 && id->_length<=sizeof(FSSpec), kODErrAssertionFailed);
  217.     ODBlockMove(id->_buffer,&fss,sizeof(FSSpec));
  218. }
  219.  
  220. static ODSession*
  221. GetSession( Environment *ev, ODDocument *document )
  222. {
  223.     return document->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  224. }
  225.  
  226. static ODSession*
  227. GetSession( Environment *ev, ODWindow *window )
  228. {
  229.     return GetSession(ev,GetDocument(ev,window));
  230. }
  231.  
  232. static ODSession*
  233. GetSession( Environment *ev, ODPersistentObject *po )
  234. {
  235.     return po->GetStorageUnit(ev)->GetSession(ev);
  236. }
  237.  
  238.  
  239. //==============================================================================
  240. #pragma mark    TITLE-BAR CLICKS
  241. //==============================================================================
  242.  
  243.  
  244.    /////////////////////////////////////////////////////////////
  245.   //    TrackWindowPathPopUp                                 //
  246.  //            Called from any click in title bar                //
  247. /////////////////////////////////////////////////////////////
  248. ODBoolean
  249. TrackWindowPathPopUp( Environment *ev, ODWindow *w, Point where )
  250. {
  251.     KeyMap keys;
  252.     GetKeys(keys);
  253.     
  254.     if( ! BitTst(&keys,0x30) )                        // Must be holding down Command key
  255.         return kODFalse;
  256.         
  257.     WindowPtr wp = w->GetPlatformWindow(ev);
  258.     if( !((WindowPeek)wp)->hilited )
  259.         return kODFalse;                            // Window must be active
  260.     
  261.     if( w->IsFloating(ev) || !w->GetDraft(ev) )        // Must not be floating window
  262.         return kODFalse;                            // and must have a draft
  263.         
  264.     ODFrame *frame = w->GetRootFrame(ev);            // Must have an OpenDoc frame
  265.     if( !frame )
  266.         return kODFalse;
  267.         
  268.     Str255 title;
  269.     GetWTitle(wp,title);
  270.     SetPort(LMGetWMgrPort());
  271.     short titleWidth = StringWidth(title);
  272.     SetPort(wp);
  273.     GlobalToLocal(&where);
  274.     
  275.     if( abs(where.h-(wp->portRect.right-wp->portRect.left)/2) <= titleWidth/2 ) {
  276.     
  277.         // Where does the pop-up go?
  278.         Point popWhere;
  279.         popWhere.h = (wp->portRect.left+wp->portRect.right-titleWidth)/2 + kMenuOffset.h;
  280.         LocalToGlobal(&popWhere);
  281.         popWhere.v = (**((WindowPeek)wp)->strucRgn).rgnBBox.top + kMenuOffset.v;
  282.     
  283.         CUsingLibraryResources u;
  284.         
  285.         // Build the pop-up:
  286.         MenuHandle m = NewMenu(kPartPopUpMenuID,"\p");
  287.         if( !m ) return kODTrue;
  288.         ODFrame *f1 = WalkFrameHierarchy(ev,frame,m);
  289.         ODReleaseObject(ev,f1);
  290.         
  291.         // Pop it up:
  292.         FSSpec fss;
  293.         GetDocumentFileSpec(ev,w,fss);
  294.         short item= TitlePopUpSelect(wp, fss, m, popWhere);
  295.         
  296.         // If user selected a parent frame, show its window & select the frame:
  297.         if( item>1 && item<=CountMItems(m) ) {
  298.             TempODFrame f2 = WalkFrameHierarchy(ev,frame,kODNULL,item);
  299.             TempODWindow w = f2->AcquireWindow(ev);
  300.             w->Select(ev);
  301.         }
  302.         
  303.         DisposeMenu(m);
  304.         return kODTrue;
  305.         
  306.     } else
  307.         return kODFalse;
  308. }
  309.  
  310.  
  311. //==============================================================================
  312. #pragma mark    BUILDING THE POP-UP
  313. //==============================================================================
  314.  
  315.  
  316. inline void
  317. ClearPartMenuIcons( )
  318. {
  319.     gNKindIcons = 1;
  320.     gIconKind[0] = kODNULL;        // Reserve one icon as a default
  321. }
  322.  
  323.  
  324.    /////////////////////////////////////////////////////////////
  325.   //    GetPartMenuIcon                                         //
  326.  //            Return an icon ID to use for a part                //
  327. /////////////////////////////////////////////////////////////
  328. static short
  329. GetPartMenuIcon( Environment *ev, ODFrame *frame )
  330. {
  331.     TempODPart    part = frame->AcquirePart(ev);
  332.     ODType        kind = ODGetKind(ev, part);
  333.     short i;
  334.     for( i=0; i<gNKindIcons; i++ )
  335.         if( gIconKind[i]==kind || ODISOStrEqual(gIconKind[i],kind) )
  336.             return kKindIconBase+i;                        // Already have an icon
  337.     if( gNKindIcons==kMaxNKindIcons )
  338.         return kKindIconBase+0;                            // Default icon
  339.     else {
  340.         gIconKind[gNKindIcons++] = kind;                // Remember a new kind
  341.         
  342.         // A slightly sick way to customize the icon in the pop-up.
  343.         // Get the SICN and copy the appropriate 'ics#' data into it in memory.
  344.         // Since the resource is never written back to disk, and the resource
  345.         // file will be closing right afterwards, this is safe to do:
  346.         IconSuite partIconSuite = ODGetIconFamily(ev, frame);
  347.         if( partIconSuite ) {
  348.             Handle icon;
  349.             (void) GetIconFromSuite(&icon, partIconSuite, 'ics#');
  350.             if( icon ) {
  351.                 Handle sicn = Get1Resource('SICN',256+kKindIconBase+i);
  352.                 if( sicn )
  353.                     ODBlockMove(*icon,*sicn,GetHandleSize(sicn));
  354.             }
  355.             DisposeIconSuite(partIconSuite,true);
  356.         }
  357.         return kKindIconBase+i;
  358.     }
  359. }
  360.  
  361.  
  362.    /////////////////////////////////////////////////////////////
  363.   //    GetNameForPart                                         //
  364.  //            Create an IText with a name for this part        //
  365. /////////////////////////////////////////////////////////////
  366. static ODIText*
  367. GetNameForPart( Environment *ev, ODPart *part )
  368. {
  369.     // Come up with something to call the part: either its real name,
  370.     // its editor name, or at last resort its SOM class name.
  371.     
  372.     ODIText* partName = ODGetPOName(ev, part, kODNULL);
  373.     if( partName )
  374.         return partName;
  375.  
  376.     // Part itself has no name, so use editor name:
  377.     ODEditor editorID = ((ODPartWrapper*)part)->GetEditor(ev);
  378.     if( GetUserEditorFromEditor(GetSession(ev,part)->GetNameSpaceManager(ev), editorID, &partName) )
  379.         return CopyIText(partName);
  380.  
  381.     // Could not get editor name, resort to SOM classname:
  382.     char *namePtr = editorID;
  383.     char *lastcolon = strrchr(namePtr,':');
  384.     if( lastcolon )
  385.         namePtr = lastcolon+1;        // Use last segment of name
  386.     return CreateITextCString(smRoman,langEnglish,namePtr);
  387. }
  388.  
  389.  
  390.    /////////////////////////////////////////////////////////////
  391.   //    WalkFrameHierarchy                                     //
  392.  //            Make the frame-hierarchy pop-up menu            //
  393. /////////////////////////////////////////////////////////////
  394. static ODFrame*
  395. WalkFrameHierarchy( Environment *ev, ODFrame *startFrame, MenuHandle m, short stopAtItem )
  396. {
  397.     /*    This has two purposes. (1) it builds the initial pop-up menu for the title-bar.
  398.         The HFS path of the document will be appended to this before the user sees it.
  399.         (2) If the user chooses one of the items added to the menu by this routine,
  400.         it's called again, with no menu but stopAtItem set, to determine which frame
  401.         corresponded to that item.
  402.         ** You must release the frame returned by this function **
  403.     */
  404.     
  405.     ClearPartMenuIcons();
  406.     
  407.     startFrame->Acquire(ev);                    // It will be released later
  408.     TempODFrame frame = startFrame;                // Reference to current frame, on our walk
  409.     TempODFrame parent = kODNULL;                // Reference to its parent frame
  410.     
  411.     while( frame ) {
  412.         if( --stopAtItem <= 0 )
  413.             break;
  414.         
  415.         // Find the parent frame, going to the parent window if necessary:
  416.         {
  417.             TempODWindow frameWindow = kODNULL;
  418.             parent = frame->AcquireContainingFrame(ev);
  419.             
  420.             if( !parent ) {
  421.                 frameWindow = frame->AcquireWindow(ev);
  422.                 parent = frameWindow->AcquireSourceFrame(ev);
  423.                 if( parent ) {
  424.                     ODFrame *parent2 = parent->AcquireContainingFrame(ev);  // -- TÇ: swapping refcounts here
  425.                     parent->Release(ev);                                     // -- TÇ: swapping refcounts here
  426.                     parent = parent2;
  427.                 }
  428.             }
  429.             
  430.             if( m ) {
  431.                 // Add menu item for this frame:
  432.                 TempODPart part = frame->AcquirePart(ev);
  433.                 Str255 nameStr;
  434.                 
  435.                 AppendMenu(m,"\pX");
  436.                 short mItem = CountMItems(m);
  437.                 SetItemIcon(m,mItem,GetPartMenuIcon(ev, frame));
  438.                 SetItemCmd(m,mItem,0x1E);
  439.     
  440.                 if( frameWindow )                                // Use window title if possible
  441.                     GetWTitle(frameWindow->GetPlatformWindow(ev),nameStr);
  442.                 else
  443.                     nameStr[0] = 0;
  444.                     
  445.                 if( nameStr[0] == 0 ) {
  446.                     ODIText *t = GetNameForPart(ev,part);        // Else use part's name
  447.                     if( t ) {
  448.                         GetITextPString(t,nameStr);
  449.                         short s = GetITextScriptCode(t);
  450.                         if( s != GetScriptManagerVariable(smSysScript) ) {
  451.                             SetItemCmd(m, mItem, kUseSpecificScript);    // Force script
  452.                             SetItemIcon(m, mItem, s);
  453.                         }
  454.                         DisposeIText(t);
  455.                     }
  456.                 }
  457.                 SetMenuItemText(m,mItem,nameStr);
  458.             }
  459.             
  460.             frame.Release();        // Forget current frame,
  461.             frame = (ODFrame*)parent;            // switch to parent
  462.             parent = kODNULL;
  463.         }
  464.     }
  465.     
  466.     return frame.DontRelease();        // Return frame, don't release it (caller must do so)
  467. }
  468.  
  469.  
  470. /*=======================================================================================*/
  471. #pragma mark    TITLE POP-UP
  472. /*=======================================================================================*/
  473.  
  474.  
  475. const short kTitlePopUpMenuID = 30000;        // Created on the fly
  476. const long kRootDir = 2;
  477.  
  478. // 'SICN' resource IDs for the icons in the path menu.
  479. // BuildPathMenu assumes these icons are in the resource chain and not overridden
  480. // by any other icons.
  481. enum {
  482.     kDocumentSICN = 257, /*unused*/
  483.     kFolderSICN,
  484.     kTrashSICN,    /*unused*/
  485.     kDiskSICN,
  486.     kFloppySICN,
  487.     kDesktopSICN
  488. };
  489.  
  490.  
  491.    /////////////////////////////////////////////////////////////
  492.   //    BuildPathMenu                                         //
  493.  //            Make the pop-up menu for the HFS path             //
  494. /////////////////////////////////////////////////////////////
  495. static void
  496. BuildPathMenu( FSSpec *spec, MenuHandle m, short stopAtItem )
  497. {
  498.     // This routine assumes that spec is a file, not a directory.
  499.     
  500.     stopAtItem++;
  501.     
  502.     short vol = spec->vRefNum;
  503.     long  dir = 0;
  504.     
  505.     long desktopDir;
  506.     short foundVol;
  507.     THROW_IF_ERROR( FindFolder(vol,kDesktopFolderType, true, &foundVol,&desktopDir) );
  508.     
  509.     for( short item=1; item<stopAtItem; item++ ) {
  510.         // Get the name of the current' item's parent dir, and the parent ID of that:
  511.         long parent;
  512.         dir = spec->parID;
  513.         if( GetParentID(vol,spec->parID,NULL, &parent) != noErr )    // Get next parent
  514.             break;
  515.         if( GetDirName(vol,spec->parID, spec->name) != noErr )        // Get name of current parent
  516.             break;
  517.         spec->parID = parent;
  518.  
  519.         // Add the current item to the menu:
  520.         if( m ) {
  521.             AppendMenu(m,"\pX");                    // Two steps in case...
  522.             short mItem = CountMItems(m);
  523.             if( dir==desktopDir )
  524.                 ODGetString(spec->name,kODDesktopTitleStrID);
  525.             SetMenuItemText(m,mItem,spec->name);    // ...spec->name contains meta-chars
  526.             short icon;
  527.             if( dir==desktopDir )
  528.                 icon = kDesktopSICN - 256;
  529.             else if( dir!=kRootDir )
  530.                 icon = kFolderSICN - 256;
  531.             else if( VolumeIsFloppy(vol) )
  532.                 icon = kFloppySICN - 256;
  533.             else
  534.                 icon = kDiskSICN - 256;
  535.             SetItemIcon(m,mItem,icon);
  536.             SetItemCmd(m,mItem,0x1E);
  537.         }
  538.         
  539.         // Quit when we reach the desktop or volume root:
  540.         if( dir==desktopDir || dir==kRootDir )
  541.             break;
  542.     }
  543. }
  544.  
  545.  
  546.    /////////////////////////////////////////////////////////////
  547.   //    TitlePopUpSelect                                     //
  548.  //            Big kahuna that runs the pop-up                    //
  549. /////////////////////////////////////////////////////////////
  550. static short
  551. TitlePopUpSelect( WindowPtr w, const FSSpec &doc, MenuHandle m, Point where )
  552. {
  553.     short prevItems = CountMItems(m);
  554.     FSSpec itemSpec = doc;
  555.     
  556.     BuildPathMenu(&itemSpec,m,32000);                            // Append path to file to the menu
  557.     
  558.     InsertMenu(m,-1);
  559.     short item= (short) PopUpMenuSelect(m,where.v,where.h, 1);        // Shazam! Pop up the menu
  560.     DeleteMenu((**m).menuID);
  561.     
  562.     for( short count = CountMItems(m); count>prevItems; count-- )    // Restore to prev state
  563.         DeleteMenuItem(m,count);
  564.     
  565.     if( item > prevItems && item>1 ) {                        // Item 1 is just the document itself
  566.         FSSpec parentSpec = doc;
  567.         BuildPathMenu(&parentSpec,NULL,item-prevItems);        // Folder to open
  568.         itemSpec = doc;
  569.         BuildPathMenu(&itemSpec,NULL,item-prevItems-1);        // Item in folder to reveal
  570.         OSErr err = RevealFinderIcon(itemSpec,parentSpec);    // Tell the Finder to reveal it
  571.     }
  572.     return item;
  573. }
  574.  
  575.  
  576. /*============================================================================================*/
  577. #pragma mark    TALKING TO THE FINDER
  578. /*============================================================================================*/
  579.  
  580.  
  581. #define kFinderSignature    'MACS'
  582. #define kFinderEventClass    'FNDR'
  583. #define kFinderRevealEvent    'srev'
  584. #define keyFinderSelection    'fsel'
  585.  
  586.  
  587.    /////////////////////////////////////////////////////////////
  588.   //    CreateFinderRevealEvent                                 //
  589.  //            Build an AEvt for revealing an item                //
  590. /////////////////////////////////////////////////////////////
  591. static OSErr
  592. CreateFinderRevealEvent( const FSSpec *itemToReveal, const FSSpec *parentFolder, AEDesc *evt )
  593. {
  594.     OSErr err;
  595.     OSType finderSignature = kFinderSignature;
  596.     AliasHandle alias = NULL;
  597.     AEDesc target = {typeNull,NULL};
  598.     AEDescList list = {typeNull,NULL};
  599.     
  600.     evt->dataHandle = NULL;
  601.     
  602.     err= AECreateDesc(typeApplSignature,&finderSignature,sizeof(OSType), &target);
  603.     if( err ) goto exit;
  604.     err= AECreateAppleEvent(kFinderEventClass, kFinderRevealEvent,
  605.                             &target, kAutoGenerateReturnID, kAnyTransactionID,
  606.                             evt);
  607.     if( err ) goto exit;
  608.     AEDisposeDesc(&target);
  609.     
  610.     err= NewAlias(NULL,parentFolder,&alias);            // Parent folder param must be full alias
  611.     if( err ) goto exit;
  612.     HLockHi((Handle)alias);
  613.     err= AEPutParamPtr(evt,keyDirectObject, typeAlias,*alias,GetHandleSize((Handle)alias));
  614.     DisposeHandle((Handle)alias);
  615.     alias = NULL;
  616.     
  617.     err= NewAliasMinimal(itemToReveal,&alias);
  618.     if( err ) goto exit;
  619.  
  620.     err= AECreateList(NULL,0,false, &list);
  621.     if( err ) goto exit;
  622.     err= AEPutPtr(&list,1,typeAlias,*alias,GetHandleSize((Handle)alias));
  623.     if( err ) goto exit;
  624.     
  625.     err= AEPutParamDesc(evt,keyFinderSelection, &list);
  626.     if( err ) goto exit;
  627.  
  628. exit:
  629.     AEDisposeDesc(&target);
  630.     AEDisposeDesc(&list);
  631.     if( alias ) DisposeHandle((Handle)alias);
  632.     if( err )
  633.         AEDisposeDesc(evt);
  634.     
  635.     return err;
  636. }
  637.  
  638.  
  639.    /////////////////////////////////////////////////////////////
  640.   //    ActivateFinder                                         //
  641.  //            Make the Finder the front process                //
  642. /////////////////////////////////////////////////////////////
  643. static void
  644. ActivateFinder( )
  645. {
  646.     OSErr err;
  647.     ProcessSerialNumber process = {0,kNoProcess};
  648.     for(;;) {
  649.         err= GetNextProcess(&process);
  650.         if( err )
  651.             break;
  652.         ProcessInfoRec info;
  653.         info.processInfoLength = sizeof(info);
  654.         info.processName = NULL;
  655.         info.processAppSpec = NULL;
  656.         err= GetProcessInformation(&process,&info);
  657.         if( err )
  658.             break;
  659.         if( info.processSignature == kFinderSignature ) {
  660.             err= SetFrontProcess(&process);
  661.             if( err )
  662.                 break;
  663.             else
  664.                 return;
  665.         }
  666.     }
  667.     WARN("Couldn't activate Finder!");
  668. }
  669.  
  670.  
  671.    /////////////////////////////////////////////////////////////
  672.   //    RevealFinderIcon                                     //
  673.  //            Send the Finder an AEvt for revealing an item    //
  674. /////////////////////////////////////////////////////////////
  675. static OSErr
  676. RevealFinderIcon( const FSSpec &itemToReveal, const FSSpec &parentFolder )
  677. {
  678.     OSErr err;
  679.     AppleEvent evt, reply;
  680.     
  681.     err= CreateFinderRevealEvent(&itemToReveal,&parentFolder, &evt);
  682.     TempAEDesc tempErr(&evt); // make sure it is disposed
  683.     if( !err )
  684.         err= AESend(&evt,&reply, kAENoReply|kAEAlwaysInteract|kAECanSwitchLayer,
  685.                     kAENormalPriority, kNoTimeOut, NULL,NULL);
  686.     if( !err )
  687.         ActivateFinder();
  688.     return err;
  689. }
  690.  
  691.  
  692. /*============================================================================================*/
  693. #pragma mark    SWIPED FROM MOREFILES 1.2.1
  694. /*============================================================================================*/
  695.  
  696.  
  697. static    OSErr    GetParentID(short vRefNum,
  698.                             long dirID,
  699.                             StringPtr name,
  700.                             long *parID)
  701. {
  702.     CInfoPBRec pb;
  703.     OSErr error;
  704.     
  705.     pb.hFileInfo.ioNamePtr = name;
  706.     pb.hFileInfo.ioVRefNum = vRefNum;
  707.     pb.hFileInfo.ioDirID = dirID;
  708.     pb.hFileInfo.ioFDirIndex = name ?0 :-1;
  709.     error = PBGetCatInfoSync(&pb);
  710.     *parID = pb.hFileInfo.ioFlParID;
  711.     return ( error );
  712. }
  713.  
  714.  
  715. static    OSErr    GetDirName(short vRefNum,
  716.                            long dirID,
  717.                            StringPtr name)
  718.         {
  719.     CInfoPBRec pb;
  720.  
  721.     pb.hFileInfo.ioNamePtr = name;
  722.     pb.hFileInfo.ioVRefNum = vRefNum;
  723.     pb.hFileInfo.ioDirID = dirID;
  724.     pb.hFileInfo.ioFDirIndex = -1;    /* get information about ioDirID */
  725.     return ( PBGetCatInfoSync(&pb) );
  726. }
  727.  
  728.  
  729. static    OSErr    GetFileLocation(short refNum,
  730.                                 short *vRefNum,
  731.                                 long *dirID,
  732.                                 StringPtr fileName)
  733. {
  734.     FCBPBRec pb;
  735.     OSErr error;
  736.  
  737.     pb.ioNamePtr = fileName;
  738.     pb.ioVRefNum = 0;
  739.     pb.ioRefNum = refNum;
  740.     pb.ioFCBIndx = 0;
  741.     error = PBGetFCBInfoSync(&pb);
  742.     *vRefNum = pb.ioFCBVRefNum;
  743.     *dirID = pb.ioFCBParID;
  744.     return ( error );
  745. }
  746.  
  747.  
  748. static    OSErr    FSpGetFileLocation(short refNum,
  749.                                    FSSpec *spec)
  750. {
  751.     return ( GetFileLocation(refNum, &(spec->vRefNum), &(spec->parID), spec->name) );
  752. }
  753.  
  754.  
  755. static    OSErr    FindDrive(StringPtr pathname,
  756.                           short vRefNum,
  757.                           DrvQElPtr *driveQElementPtr)
  758. {
  759.     OSErr            result;
  760.     Str255            tempPathname;
  761.     HParamBlockRec    hPB;
  762.     short            driveNumber;
  763.     
  764.     *driveQElementPtr = NULL;
  765.     
  766.     /* First, use PBHGetVInfo to determine the volume */
  767.     hPB.volumeParam.ioVRefNum = vRefNum;
  768.     if ( pathname == NULL )
  769.     {
  770.         hPB.volumeParam.ioNamePtr = NULL;
  771.         hPB.volumeParam.ioVolIndex = 0;    /* use ioVRefNum only */
  772.     }
  773.     else
  774.     {
  775.         ODBlockMove(pathname, tempPathname, pathname[0] + 1);    /* make a copy of the string and */
  776.         hPB.volumeParam.ioNamePtr = (StringPtr)tempPathname;    /* use the copy so original isn't trashed */
  777.         hPB.volumeParam.ioVolIndex = -1;    /* use ioNamePtr/ioVRefNum combination */
  778.     }
  779.     result = PBHGetVInfoSync(&hPB);
  780.     if ( result == noErr )
  781.     {
  782.         /*
  783.         **    The volume can be either online, offline, or ejected. What we find in
  784.         **    ioVDrvInfo and ioVDRefNum will tell us which it is.
  785.         **    See Inside Macintosh: Files page 2-80 and the Technical Note
  786.         **    "FL 34 - VCBs and Drive Numbers : The Real Story"
  787.         **    Where we get the drive number depends on the state of the volume.
  788.         */
  789.         if ( hPB.volumeParam.ioVDrvInfo != 0 )
  790.         {
  791.             /* The volume is online and not ejected */
  792.             /* Get the drive number */
  793.             driveNumber = hPB.volumeParam.ioVDrvInfo;
  794.         }
  795.         else
  796.         {
  797.             /* The volume's is either offline or ejected */
  798.             /* in either case, the volume is NOT online */
  799.  
  800.             /* Is it ejected or just offline? */
  801.             if ( hPB.volumeParam.ioVDRefNum > 0 )
  802.             {
  803.                 /* It's ejected, the drive number is ioVDRefNum */
  804.                 driveNumber = hPB.volumeParam.ioVDRefNum;
  805.             }
  806.             else
  807.             {
  808.                 /* It's offline, the drive number is the negative of ioVDRefNum */
  809.                 driveNumber = (short)-hPB.volumeParam.ioVDRefNum;
  810.             }
  811.         }
  812.         
  813.         /* Get pointer to first element in drive queue */
  814.         *driveQElementPtr = (DrvQElPtr)(GetDrvQHdr()->qHead);
  815.         
  816.         /* Search for a matching drive number */
  817.         while ( (*driveQElementPtr != NULL) && ((*driveQElementPtr)->dQDrive != driveNumber) )
  818.         {
  819.             *driveQElementPtr = (DrvQElPtr)(*driveQElementPtr)->qLink;
  820.         }
  821.         
  822.         if ( *driveQElementPtr == NULL )
  823.         {
  824.             /* This should never happen since every volume must have a drive, but... */
  825.             result = nsDrvErr;
  826.         }
  827.     }
  828.     
  829.     return ( result );
  830. }
  831.  
  832. static ODBoolean VolumeIsFloppy( short vRefNum )
  833. {
  834.     DrvQElPtr q;
  835.     return FindDrive(NULL,vRefNum,&q)==noErr && q->dQRefNum==kFloppyDriverRefNum;
  836. }
  837.